<?php
  class iJFactory {
    protected static $class_storage;
    protected static $class_location;
    
    


    public function __construct() {

    }
    
    public static function singleton($class_name) {
        if(array_key_exists($class_name, self::$class_storage)) {
          return self::$class_storage[$class_name];
        } else {
          $classes = iJScanDir(DIR_CLASSES);
          if(isset($classes[$class_name])) {
            require($classes[$class_name]);
            eval("\$object = new $class_name();");
            self::$class_storage[$class_name]  = $object; 
            return  $object;
          }
          
          $classes = iJScanDir(DIR_BLOCKS);
         
          if(isset($classes[$class_name])) {
            require($classes[$class_name]);
           // spr('$object = new $class_name()');
            eval("\$object = new $class_name();");
            self::$class_storage[$class_name]  = $object; 
            return  $object;
          }
          
          return null;
        }
    }
    
    
    

    public static function init() {

      $classes    = iJScanDir(DIR_CORE);
      $interface  = iJScanDir(DIR_INTERFACES);
            
      foreach($interface as $class_name => $path) {          
        require($path);               
      }
      
      foreach($classes as $class_name => $path) {
        if($class_name == 'iJFactory') continue;
        if(!in_array($path, $interface)) {
          require($path);
          eval("\$object = new $class_name();");
          self::$class_storage[$class_name]  = $object;     
        }  
      }
       
      $classes = iJScanDir(DIR_STATIC_CLASSES);
      foreach($classes as $class_name => $path) {
        require($path);    
      }
    }
    
    public static function getLocation($className) {
      $classes = iJScanDir(DIR_CLASSES);
      if(isset($classes[$className])) { 
        return $classes[$className];
      } else {
        $classes = iJScanDir(DIR_BLOCKS);
        if(isset($classes[$className])) { 
          return $classes[$className];
        } else {
          $classes = iJScanDir(DIR_STATIC_CLASSES);
          if(isset($classes[$className])) { 
            return $classes[$className];
          } else {
            $classes = iJScanDir(DIR_CORE);
            $classFileName = $className;
            if(isset($classes[$classFileName])) { 
              return $classes[$classFileName];
            } else {
              return false;
            }
          }
          
        }
        
      }
    }
    
    public static function includeClass($class_name) {
      if($dir == '') {
        $classes = iJScanDir(DIR_CLASSES);
        if(isset($classes[$class_name])) { 
          require($classes[$class_name]);
          return true;
        } else {
          return false;
        }
      }
      
    }

    
    /**
     * call
     *
     * This method for static method call of object
     *
     * @param string $class_name - name of a class
     * @param string $method_name - parameters
     *
     * @return result of requested method, otherwise null
     *
     * @access public
     *
     * @static
     */
    public static function call($class_name, $method_name) {
      $object = self::singleton($class_name);
      if (!is_null($object)) {
        $params_list   = '';
        $func_num_args = func_num_args();
        if ($func_num_args > 2) {
          for($i = 2; $i < $func_num_args; $i++) {
            $params[] = '$params[' . $i . ']';
          }
          $params_list = implode(',', $params);
          $params = func_get_args();
        }
        eval("\$object = $class_name::$method_name($params_list);");
        return $object;
      } else {
        echo 'Failed calling of class: ' . $class_name . ';<br>';
      }

      
    }
    
   /* 
    public static function existClassFile($class_name) {
        if(isset(self::$class_storage[$class_name])) {
            return true;
        } else {
            return false;
        }
    }
    */


  }
?>